package org.springframework.orm.ibatis3.support;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.springframework.beans.factory.FactoryBean;

/**
 * BeanFactory that enables inyection of iBATIS Mapper Interfaces.
 *
 * <p>The implementation consists on a simple JDK proxy that fordwards 
 * method invocations to the real mapper got from SqlSessionTemplate
 *
 * @author Eduardo Macarrón
 * @since 3.0
 * @see #SqlSessionDaoSupport
 * @see #setSqlSessionTemplate
 * @see org.springframework.orm.ibatis3.support.SqlSessionDaoSupport
 * @see org.springframework.orm.ibatis3.SqlSessionTemplate
 */

public class IBatisMapperFactoryBean extends SqlSessionDaoSupport implements FactoryBean<Object>, InvocationHandler {

	private Object proxy;
	private Class<?> mapperInterface;

	public Class<?> getMapperInterface() {
		return mapperInterface;
	}

	public void setMapperInterface(Class<?> mapperInterface) {
		this.mapperInterface = mapperInterface;
	}

	
	public Object getObject() throws Exception {
		if (proxy == null)
			proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(),
					new Class[] { mapperInterface }, this);

		return proxy;
	}

	
	public Class<?> getObjectType() {
		return mapperInterface;
	}

	
	public boolean isSingleton() {
		return true;
	}

	public final Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		return method.invoke(getSqlSessionTemplate().getMapper(mapperInterface), args);
	}	
}
